Skip to content

Conversation

@ericallam
Copy link
Member

@ericallam ericallam commented Sep 16, 2025

Prevent uncaught errors in the onSuccess, onComplete, and onFailure lifecycle hooks from failing attempts/runs.

Deprecated the onStart lifecycle hook (which only fires before the run function on the first attempt). Replaced with onStartAttempt that fires before the run function on every attempt:

export const taskWithOnStartAttempt = task({
  id: "task-with-on-start-attempt",
  onStartAttempt: async ({ payload, ctx }) => {
    //...
  },
  run: async (payload: any, { ctx }) => {
    //...
  },
});

// Default a global lifecycle hook using tasks
tasks.onStartAttempt(({ ctx, payload, task }) => {
  console.log(
    `Run ${ctx.run.id} started on task ${task} attempt ${ctx.run.attempt.number}`,
    ctx.run
  );
});

If you want to execute code before just the first attempt, you can use the onStartAttempt function and check ctx.run.attempt.number === 1:

export const taskWithOnStartAttempt = task({
  id: "task-with-on-start-attempt",
  onStartAttempt: async ({ payload, ctx }) => {
    if (ctx.run.attempt.number === 1) {
      console.log("Run started on attempt 1", ctx.run);
    }
  },
});

@changeset-bot
Copy link

changeset-bot bot commented Sep 16, 2025

🦋 Changeset detected

Latest commit: 23930b6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 24 packages
Name Type
@trigger.dev/sdk Minor
@trigger.dev/python Minor
d3-chat Patch
references-d3-openai-agents Patch
references-nextjs-realtime Patch
references-realtime-streams Patch
@trigger.dev/build Minor
@trigger.dev/core Minor
@trigger.dev/react-hooks Minor
@trigger.dev/redis-worker Minor
@trigger.dev/rsc Minor
@trigger.dev/schema-to-json Minor
@trigger.dev/database Minor
@trigger.dev/otlp-importer Minor
trigger.dev Minor
@internal/cache Patch
@internal/clickhouse Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/schedule-engine Patch
@internal/testcontainers Patch
@internal/tracing Patch
@internal/zod-worker Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 16, 2025

Walkthrough

This pull request introduces a new onStartAttempt lifecycle hook that fires before each task attempt, replacing the deprecated onStart hook which only fires before the first attempt. The changes add comprehensive support for the new hook across the codebase: new type definitions in the core lifecycle hooks infrastructure, extended hook managers and registries, updated task executor logic to invoke the hooks at appropriate points, public API exports in both core and SDK packages, comprehensive documentation updates with deprecation guidance, a UI component update to handle the new hook type in run displays, and test coverage for the new hook behavior and adjusted error handling semantics. The implementation also refines error handling for onSuccess, onFailure, and onComplete hooks to prevent error propagation, and adjusts init hook result aggregation logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • packages/core/src/v3/workers/taskExecutor.ts — Most critical file; contains complex logic changes including the new #callOnStartAttemptFunctions invocation, modified error handling for onSuccess/onFailure/onComplete hooks, and enhanced init hook result merging. Requires careful verification of execution order and error propagation semantics.
  • packages/core/test/taskExecutor.test.ts — New tests should be validated to ensure they adequately cover the new onStartAttempt hook execution order, the error-non-propagation behavior for onSuccess, and init result merging scenarios.
  • docs/tasks/overview.mdx — Extensive documentation rewrite with deprecation guidance; verify examples are accurate and migration paths are clear, especially regarding the ctx.run.attempt.number pattern for first-attempt detection.
  • packages/core/src/v3/lifecycleHooks/ (types.ts, manager.ts, index.ts) — Type definitions and manager implementations are straightforward additions but should be checked for consistency with existing hook patterns and proper interface alignment across all manager implementations (both Standard and Noop variants).

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description fails to follow the required template, missing the Checklist, Testing, Changelog, and Screenshots sections entirely. Add all required template sections including the Checklist, Testing steps, Changelog, and Screenshots sections even if some are marked as N/A.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: replacing the onStart lifecycle hook with onStartAttempt.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ea-branch-88

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6984903 and 23930b6.

📒 Files selected for processing (2)
  • apps/webapp/app/components/runs/v3/RunIcon.tsx (1 hunks)
  • packages/core/src/v3/types/tasks.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations

Files:

  • apps/webapp/app/components/runs/v3/RunIcon.tsx
  • packages/core/src/v3/types/tasks.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

We use zod a lot in packages/core and in the webapp

Files:

  • apps/webapp/app/components/runs/v3/RunIcon.tsx
  • packages/core/src/v3/types/tasks.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json

Files:

  • apps/webapp/app/components/runs/v3/RunIcon.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to trigger.config.ts : Configure global task lifecycle hooks (onStart/onSuccess/onFailure) only within trigger.config.ts if needed, not within arbitrary files
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Define tasks using task({ id, run, ... }) with a unique id per project

Applied to files:

  • apps/webapp/app/components/runs/v3/RunIcon.tsx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to trigger.config.ts : Configure global task lifecycle hooks (onStart/onSuccess/onFailure) only within trigger.config.ts if needed, not within arbitrary files

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Do not use client.defineJob or any deprecated v2 patterns (e.g., eventTrigger) when defining tasks

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schemaTask({ schema, run, ... }) to validate payloads when input validation is required

Applied to files:

  • packages/core/src/v3/types/tasks.ts
🧬 Code graph analysis (1)
packages/core/src/v3/types/tasks.ts (3)
packages/trigger-sdk/src/v3/shared.ts (1)
  • Context (122-122)
packages/core/src/v3/lifecycleHooks/types.ts (2)
  • OnStartHookFunction (30-32)
  • OnStartAttemptHookFunction (43-45)
packages/core/src/v3/workers/taskExecutor.ts (11)
  • payload (362-414)
  • payload (416-436)
  • payload (664-764)
  • payload (766-831)
  • payload (833-898)
  • payload (900-910)
  • payload (912-976)
  • payload (978-1040)
  • payload (1042-1050)
  • payload (1052-1122)
  • payload (1334-1399)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/webapp/app/components/runs/v3/RunIcon.tsx (1)

101-101: LGTM! Correctly adds icon support for the new onStartAttempt hook.

The new case is properly positioned with other task hook cases and follows the existing pattern by falling through to render FunctionIcon with dimmed styling, consistent with similar lifecycle hooks.

packages/core/src/v3/types/tasks.ts (3)

16-16: LGTM!

The import of OnStartAttemptHookFunction is correctly added to support the new per-attempt lifecycle hook.


337-349: LGTM!

The deprecation of onStart is clearly marked, and the new onStartAttempt option is well-documented. The explanation that it "fires before each attempt" with the tip to check ctx.attempt.number === 1 for first-attempt behavior is helpful.


933-933: LGTM once StartAttemptFnParams is corrected.

The onStartAttempt function signature is correctly added to the fns object. Once the init property is removed from StartAttemptFnParams (as noted in the previous comment), this signature will accurately reflect the runtime parameters.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (7)
.changeset/tiny-carrots-rest.md (4)

2-3: Include all affected packages in the changeset

Core types and APIs were added; ensure @trigger.dev/core (and any other published packages touched) receive a bump in this PR’s changesets, not just @trigger.dev/sdk.


20-27: Clarify file location for global hooks

Docs should state that global lifecycle hooks belong in trigger.config.ts per established guidance.

Apply this doc tweak:

-// Default a global lifecycle hook using tasks
+// Default a global lifecycle hook using tasks (in trigger.config.ts)
 tasks.onStartAttempt(({ ctx, payload, task }) => {

31-40: Code-fence filename syntax may not render

```ts /trigger/on-start-attempt.ts might not be recognized by your MDX tooling. Prefer title= or a preceding caption.


5-5: Specify logging/telemetry behavior for swallowed errors

If onSuccess/onComplete/onFailure errors no longer fail runs, note that they’re still captured in logs/metrics.

packages/core/src/v3/lifecycle-hooks-api.ts (1)

7-39: Re-export full StartAttempt types for consistency

You currently export only AnyOnStartAttemptHookFunction. Re-export OnStartAttemptHookFunction and TaskStartAttemptHookParams like other hooks to aid typing.

 export type {
   OnInitHookFunction,
   AnyOnInitHookFunction,
   RegisteredHookFunction,
   TaskInitHookParams,
   TaskStartHookParams,
   OnStartHookFunction,
   AnyOnStartHookFunction,
+  // StartAttempt
+  OnStartAttemptHookFunction,
+  TaskStartAttemptHookParams,
   TaskFailureHookParams,
   AnyOnFailureHookFunction,
   TaskSuccessHookParams,
   AnyOnSuccessHookFunction,
   TaskCompleteHookParams,
   AnyOnCompleteHookFunction,
   TaskWaitHookParams,
   AnyOnWaitHookFunction,
   TaskResumeHookParams,
   AnyOnResumeHookFunction,
   TaskCatchErrorHookParams,
   AnyOnCatchErrorHookFunction,
   TaskCompleteResult,
   TaskMiddlewareHookParams,
   AnyOnMiddlewareHookFunction,
   OnMiddlewareHookFunction,
   OnCleanupHookFunction,
   AnyOnCleanupHookFunction,
   TaskCleanupHookParams,
   TaskWait,
   TaskCancelHookParams,
   OnCancelHookFunction,
   AnyOnCancelHookFunction,
   AnyOnStartAttemptHookFunction,
 } from "./lifecycleHooks/types.js";
packages/core/src/v3/types/tasks.ts (1)

338-349: Consider clarifying the deprecation timeline for onStart.

While the deprecation notice directs users to onStartAttempt, consider adding information about when onStart will be removed to help users plan their migration.

Consider enhancing the deprecation notice:

   /**
    * onStart is called the first time a task is executed in a run (not before every retry)
    *
-   * @deprecated Use onStartAttempt instead
+   * @deprecated Use onStartAttempt instead. This will be removed in v5.0.0
    */
docs/tasks/overview.mdx (1)

359-362: Consider documenting where these suppressed errors are visible in the dashboard.

The documentation mentions that errors in onSuccess, onComplete, and onFailure are ignored but visible in the dashboard. Consider adding more specific information about where users can find these errors (e.g., in the run details, logs panel, etc.).

Would you like me to suggest more specific documentation about where these errors appear in the dashboard UI?

Also applies to: 390-393, 421-424

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 501a383 and 6170b3d.

⛔ Files ignored due to path filters (1)
  • references/hello-world/src/trigger/example.ts is excluded by !references/**
📒 Files selected for processing (14)
  • .changeset/tiny-carrots-rest.md (1 hunks)
  • apps/webapp/app/components/runs/v3/RunIcon.tsx (1 hunks)
  • docs/tasks/overview.mdx (9 hunks)
  • packages/cli-v3/package.json (1 hunks)
  • packages/core/src/v3/lifecycle-hooks-api.ts (1 hunks)
  • packages/core/src/v3/lifecycleHooks/index.ts (2 hunks)
  • packages/core/src/v3/lifecycleHooks/manager.ts (4 hunks)
  • packages/core/src/v3/lifecycleHooks/types.ts (2 hunks)
  • packages/core/src/v3/types/tasks.ts (4 hunks)
  • packages/core/src/v3/workers/taskExecutor.ts (8 hunks)
  • packages/core/test/taskExecutor.test.ts (2 hunks)
  • packages/trigger-sdk/src/v3/hooks.ts (2 hunks)
  • packages/trigger-sdk/src/v3/shared.ts (2 hunks)
  • packages/trigger-sdk/src/v3/tasks.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations

Files:

  • packages/core/src/v3/lifecycle-hooks-api.ts
  • apps/webapp/app/components/runs/v3/RunIcon.tsx
  • packages/trigger-sdk/src/v3/shared.ts
  • packages/trigger-sdk/src/v3/tasks.ts
  • packages/core/src/v3/lifecycleHooks/types.ts
  • packages/core/src/v3/lifecycleHooks/index.ts
  • packages/core/test/taskExecutor.test.ts
  • packages/core/src/v3/types/tasks.ts
  • packages/trigger-sdk/src/v3/hooks.ts
  • packages/core/src/v3/workers/taskExecutor.ts
  • packages/core/src/v3/lifecycleHooks/manager.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

We use zod a lot in packages/core and in the webapp

Files:

  • packages/core/src/v3/lifecycle-hooks-api.ts
  • apps/webapp/app/components/runs/v3/RunIcon.tsx
  • packages/core/src/v3/lifecycleHooks/types.ts
  • packages/core/src/v3/lifecycleHooks/index.ts
  • packages/core/test/taskExecutor.test.ts
  • packages/core/src/v3/types/tasks.ts
  • packages/core/src/v3/workers/taskExecutor.ts
  • packages/core/src/v3/lifecycleHooks/manager.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json

Files:

  • apps/webapp/app/components/runs/v3/RunIcon.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Our tests are all vitest

Files:

  • packages/core/test/taskExecutor.test.ts
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{ts,tsx,js,jsx}: Unit tests must use Vitest
Tests should avoid mocks or stubs and use helpers from @internal/testcontainers when Redis or Postgres are needed
Test files live beside the files under test and should use descriptive describe and it blocks

Files:

  • packages/core/test/taskExecutor.test.ts
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to trigger.config.ts : Configure global task lifecycle hooks (onStart/onSuccess/onFailure) only within trigger.config.ts if needed, not within arbitrary files
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to trigger.config.ts : Configure global task lifecycle hooks (onStart/onSuccess/onFailure) only within trigger.config.ts if needed, not within arbitrary files

Applied to files:

  • .changeset/tiny-carrots-rest.md
  • packages/trigger-sdk/src/v3/shared.ts
  • packages/trigger-sdk/src/v3/tasks.ts
  • packages/core/test/taskExecutor.test.ts
  • packages/core/src/v3/types/tasks.ts
  • docs/tasks/overview.mdx
  • packages/trigger-sdk/src/v3/hooks.ts
  • packages/core/src/v3/workers/taskExecutor.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Define tasks using task({ id, run, ... }) with a unique id per project

Applied to files:

  • .changeset/tiny-carrots-rest.md
  • packages/trigger-sdk/src/v3/tasks.ts
  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use triggerAndWait() only from within a task context (not from generic app code) and handle result.ok or use unwrap() with error handling

Applied to files:

  • .changeset/tiny-carrots-rest.md
  • packages/trigger-sdk/src/v3/tasks.ts
  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Do not use client.defineJob or any deprecated v2 patterns (e.g., eventTrigger) when defining tasks

Applied to files:

  • .changeset/tiny-carrots-rest.md
  • packages/trigger-sdk/src/v3/tasks.ts
  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Import Trigger.dev APIs from "trigger.dev/sdk/v3" when writing tasks or related utilities

Applied to files:

  • .changeset/tiny-carrots-rest.md
  • packages/trigger-sdk/src/v3/shared.ts
  • packages/trigger-sdk/src/v3/tasks.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schedules.task(...) for scheduled (cron) tasks; do not implement schedules as plain task() with external cron logic

Applied to files:

  • packages/trigger-sdk/src/v3/tasks.ts
  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : When triggering a task multiple times in a loop from inside another task, use batchTrigger()/batchTriggerAndWait() instead of per-item trigger() calls

Applied to files:

  • packages/trigger-sdk/src/v3/tasks.ts
  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schemaTask({ schema, run, ... }) to validate payloads when input validation is required

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export every task (including subtasks) defined with task(), schedules.task(), or schemaTask()

Applied to files:

  • docs/tasks/overview.mdx
🧬 Code graph analysis (7)
packages/trigger-sdk/src/v3/shared.ts (2)
packages/core/src/v3/lifecycle-hooks-api.ts (2)
  • lifecycleHooks (5-5)
  • AnyOnStartAttemptHookFunction (38-38)
packages/core/src/v3/lifecycleHooks/types.ts (1)
  • AnyOnStartAttemptHookFunction (47-47)
packages/core/src/v3/lifecycleHooks/index.ts (2)
packages/core/src/v3/lifecycleHooks/types.ts (3)
  • RegisterHookFunctionParams (182-185)
  • AnyOnStartAttemptHookFunction (47-47)
  • RegisteredHookFunction (187-191)
packages/core/src/v3/lifecycle-hooks-api.ts (2)
  • AnyOnStartAttemptHookFunction (38-38)
  • RegisteredHookFunction (10-10)
packages/core/test/taskExecutor.test.ts (3)
packages/core/src/v3/lifecycle-hooks-api.ts (1)
  • lifecycleHooks (5-5)
packages/core/src/v3/workers/taskExecutor.ts (12)
  • payload (364-416)
  • payload (418-454)
  • payload (682-782)
  • payload (784-849)
  • payload (851-916)
  • payload (918-928)
  • payload (930-994)
  • payload (996-1058)
  • payload (1060-1068)
  • payload (1070-1140)
  • payload (1352-1417)
  • result (1303-1350)
packages/core/src/v3/types/tasks.ts (1)
  • RunFnParams (89-96)
packages/core/src/v3/types/tasks.ts (3)
packages/trigger-sdk/src/v3/shared.ts (1)
  • Context (122-122)
packages/core/src/v3/lifecycleHooks/types.ts (2)
  • OnStartHookFunction (30-32)
  • OnStartAttemptHookFunction (43-45)
packages/core/src/v3/workers/taskExecutor.ts (11)
  • payload (364-416)
  • payload (418-454)
  • payload (682-782)
  • payload (784-849)
  • payload (851-916)
  • payload (918-928)
  • payload (930-994)
  • payload (996-1058)
  • payload (1060-1068)
  • payload (1070-1140)
  • payload (1352-1417)
packages/trigger-sdk/src/v3/hooks.ts (2)
packages/core/src/v3/lifecycle-hooks-api.ts (3)
  • AnyOnStartHookFunction (14-14)
  • AnyOnStartAttemptHookFunction (38-38)
  • lifecycleHooks (5-5)
packages/core/src/v3/lifecycleHooks/types.ts (2)
  • AnyOnStartHookFunction (34-34)
  • AnyOnStartAttemptHookFunction (47-47)
packages/core/src/v3/workers/taskExecutor.ts (5)
packages/core/src/utils.ts (1)
  • tryCatch (5-18)
packages/core/src/v3/schemas/common.ts (2)
  • TaskRunContext (407-417)
  • TaskRunContext (419-419)
packages/core/src/v3/lifecycle-hooks-api.ts (1)
  • lifecycleHooks (5-5)
packages/core/src/v3/run-timeline-metrics-api.ts (1)
  • runTimelineMetrics (5-5)
packages/core/src/v3/semanticInternalAttributes.ts (1)
  • SemanticInternalAttributes (1-64)
packages/core/src/v3/lifecycleHooks/manager.ts (1)
packages/core/src/v3/lifecycleHooks/types.ts (3)
  • RegisteredHookFunction (187-191)
  • AnyOnStartAttemptHookFunction (47-47)
  • RegisterHookFunctionParams (182-185)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (22)
packages/cli-v3/package.json (1)

158-158: Trailing newline only — OK

No functional change. Safe to merge.

packages/core/src/v3/lifecycleHooks/types.ts (2)

36-48: New StartAttempt hook types look good

Shape matches intent (no init), return type aligned with other hooks.


285-294: Manager surface extended — ensure Noop/impl parity

Confirm NoopLifecycleHooksManager and the concrete manager implement these four new methods to avoid runtime undefined-method errors.

packages/trigger-sdk/src/v3/tasks.ts (1)

92-95: API addition looks good; deprecation marker is clear

tasks.onStartAttempt is exposed next to onStart with a deprecation note. Back-compat maintained.

packages/trigger-sdk/src/v3/shared.ts (1)

91-95: Per-task StartAttempt hook registration wired correctly — verified

Type cast and registration follow existing patterns: core types declare onStartAttempt (packages/core/src/v3/types/tasks.ts), lifecycle registration exists (packages/core/src/v3/lifecycleHooks/index.ts, manager.ts), and taskExecutor invokes the hook (packages/core/src/v3/workers/taskExecutor.ts); tests exercise hook ordering.

apps/webapp/app/components/runs/v3/RunIcon.tsx (1)

100-107: Approve — event name confirmed

Emitted span/icon is exactly "task-hook-onStartAttempt" (packages/core/src/v3/workers/taskExecutor.ts:1017, 1044) and RunIcon maps it (apps/webapp/app/components/runs/v3/RunIcon.tsx:100).

packages/core/test/taskExecutor.test.ts (2)

272-355: LGTM! The onStartAttempt test validates the new per-attempt lifecycle hook.

The test correctly:

  • Registers global and task-specific onStartAttempt hooks
  • Verifies hooks are called in the expected order (global-1, global-2, task)
  • Confirms each hook receives the correct payload
  • Validates that the init data is properly accessible in the run function

1334-1374: LGTM! Error suppression for onSuccess hooks is correctly implemented.

The test confirms that errors thrown in onSuccess hooks do not propagate and fail the run, which aligns with the documented behavior. The run completes successfully despite the hook error.

packages/core/src/v3/types/tasks.ts (2)

118-123: LGTM! StartAttemptFnParams type is consistent with existing patterns.

The new type follows the same structure as StartFnParams, providing context, optional init data, and the abort signal.


932-932: LGTM! TaskMetadataWithFunctions correctly includes the onStartAttempt function.

The type signature matches the expected pattern with payload and StartAttemptFnParams.

packages/core/src/v3/workers/taskExecutor.ts (6)

186-186: LGTM! The onStartAttempt hook is correctly invoked after the first-attempt check.

The placement ensures the hook runs on every attempt (including the first), which aligns with the documented behavior.


800-846: LGTM! Error suppression for onSuccess hooks is implemented correctly.

The removal of error propagation ensures that hook failures don't fail the run, matching the documented behavior and test expectations.


867-913: LGTM! Error suppression for onFailure hooks is consistent.

The implementation matches the onSuccess pattern, ensuring hook errors don't propagate.


1368-1414: LGTM! Error suppression for onComplete hooks follows the same pattern.

Consistent implementation across all three hook types (onSuccess, onFailure, onComplete).


694-773: LGTM! The init hook merging logic is well-implemented.

The implementation correctly:

  • Collects results from multiple global init hooks
  • Merges them with Object.assign
  • Allows task-specific init hooks to override global results
  • Preserves error propagation for init hooks (as they should fail the attempt)

996-1058: LGTM! The onStartAttempt implementation follows established patterns.

The new hook implementation:

  • Correctly retrieves both global and task-specific hooks
  • Executes them in the right order
  • Properly propagates errors (as start-attempt errors should fail the attempt)
  • Uses appropriate telemetry attributes
packages/core/src/v3/lifecycleHooks/index.ts (1)

85-104: LGTM! StartAttempt hook registration methods follow the established pattern.

The new methods correctly delegate to the lifecycle hooks manager and maintain consistency with existing hook registration patterns.

docs/tasks/overview.mdx (2)

250-294: LGTM! The onStartAttempt documentation is comprehensive and clear.

The documentation:

  • Clearly explains the new hook's purpose
  • Shows both per-task and global usage examples
  • Provides guidance on detecting the first attempt
  • Includes important error handling information

538-571: LGTM! The deprecation notice for onStart is clear and helpful.

The deprecated section:

  • Clearly marks the feature as deprecated
  • Provides migration guidance to onStartAttempt
  • Retains the documentation for existing users
  • Explains the key difference (once per run vs. per attempt)
packages/core/src/v3/lifecycleHooks/manager.ts (3)

17-18: LGTM: added import for AnyOnStartAttemptHookFunction

Import is correct and consistent with existing patterns.


27-35: LGTM: start-attempt hook maps added

Global and per‑task maps mirror existing start/init patterns. Single per‑task hook aligns with current design elsewhere.


142-171: LGTM: standard manager APIs for start-attempt hooks

Registration and retrieval methods follow established conventions (id generation, return shapes). No issues spotted.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/trigger-sdk/src/v3/hooks.ts (1)

45-56: Overload types corrected for onStartAttempt — nice.

The overloads now use AnyOnStartAttemptHookFunction; resolves the prior mismatch.

🧹 Nitpick comments (4)
packages/core/src/v3/types/tasks.ts (1)

344-350: Fix first-attempt check in docs comment.

Use ctx.run.attempt.number, not ctx.attempt.number.

- * You can detect the first attempt by checking `ctx.attempt.number === 1`.
+ * You can detect the first attempt by checking `ctx.run.attempt.number === 1`.
packages/trigger-sdk/src/v3/hooks.ts (1)

15-16: Re-export AnyOnStartAttemptHookFunction for API parity.

Other hook types are re-exported below; add this one too for consistency.

 export type {
   AnyOnStartHookFunction,
   TaskStartHookParams,
   OnStartHookFunction,
   AnyOnFailureHookFunction,
   AnyOnSuccessHookFunction,
   AnyOnCompleteHookFunction,
   TaskCompleteResult,
   AnyOnWaitHookFunction,
   AnyOnResumeHookFunction,
   AnyOnCatchErrorHookFunction,
   AnyOnMiddlewareHookFunction,
   AnyOnCancelHookFunction,
+  AnyOnStartAttemptHookFunction,
 };
docs/tasks/overview.mdx (2)

257-266: Rename code block path to match the feature.

The section is about onStartAttempt but the snippet is labeled /trigger/on-start.ts.

-```ts /trigger/on-start.ts
+```ts /trigger/on-start-attempt.ts
 export const taskWithOnStartAttempt = task({
   id: "task-with-on-start-attempt",
   onStartAttempt: async ({ payload, ctx }) => {
     //...
   },

380-388: Correct the earlier onComplete example (uses undefined result).

The snippet above in this section references result but destructures { payload, output, ctx }. Adjust to use a result param or update the example; consider:

onComplete: async ({ result, ctx }) => {
  if (result.ok) {
    console.log("Run succeeded", result.output);
  } else {
    console.log("Run failed", result.error);
  }
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 494b659 and 6984903.

⛔ Files ignored due to path filters (2)
  • docs/images/lifecycle-functions.png is excluded by !**/*.png
  • references/hello-world/src/trigger/example.ts is excluded by !references/**
📒 Files selected for processing (14)
  • .changeset/tiny-carrots-rest.md (1 hunks)
  • apps/webapp/app/components/runs/v3/RunIcon.tsx (1 hunks)
  • docs/tasks/overview.mdx (9 hunks)
  • packages/cli-v3/package.json (1 hunks)
  • packages/core/src/v3/lifecycle-hooks-api.ts (1 hunks)
  • packages/core/src/v3/lifecycleHooks/index.ts (2 hunks)
  • packages/core/src/v3/lifecycleHooks/manager.ts (4 hunks)
  • packages/core/src/v3/lifecycleHooks/types.ts (2 hunks)
  • packages/core/src/v3/types/tasks.ts (4 hunks)
  • packages/core/src/v3/workers/taskExecutor.ts (8 hunks)
  • packages/core/test/taskExecutor.test.ts (2 hunks)
  • packages/trigger-sdk/src/v3/hooks.ts (2 hunks)
  • packages/trigger-sdk/src/v3/shared.ts (2 hunks)
  • packages/trigger-sdk/src/v3/tasks.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • .changeset/tiny-carrots-rest.md
  • packages/core/src/v3/lifecycle-hooks-api.ts
  • packages/cli-v3/package.json
  • apps/webapp/app/components/runs/v3/RunIcon.tsx
  • packages/core/src/v3/lifecycleHooks/types.ts
  • packages/core/src/v3/lifecycleHooks/manager.ts
  • packages/trigger-sdk/src/v3/tasks.ts
  • packages/core/src/v3/lifecycleHooks/index.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • packages/core/test/taskExecutor.test.ts
  • packages/core/src/v3/workers/taskExecutor.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations

Files:

  • packages/trigger-sdk/src/v3/hooks.ts
  • packages/core/src/v3/types/tasks.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

We use zod a lot in packages/core and in the webapp

Files:

  • packages/core/src/v3/types/tasks.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to trigger.config.ts : Configure global task lifecycle hooks (onStart/onSuccess/onFailure) only within trigger.config.ts if needed, not within arbitrary files
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to trigger.config.ts : Configure global task lifecycle hooks (onStart/onSuccess/onFailure) only within trigger.config.ts if needed, not within arbitrary files

Applied to files:

  • packages/trigger-sdk/src/v3/hooks.ts
  • packages/core/src/v3/types/tasks.ts
  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schemaTask({ schema, run, ... }) to validate payloads when input validation is required

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Define tasks using task({ id, run, ... }) with a unique id per project

Applied to files:

  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schedules.task(...) for scheduled (cron) tasks; do not implement schedules as plain task() with external cron logic

Applied to files:

  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use triggerAndWait() only from within a task context (not from generic app code) and handle result.ok or use unwrap() with error handling

Applied to files:

  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : When triggering a task multiple times in a loop from inside another task, use batchTrigger()/batchTriggerAndWait() instead of per-item trigger() calls

Applied to files:

  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export every task (including subtasks) defined with task(), schedules.task(), or schemaTask()

Applied to files:

  • docs/tasks/overview.mdx
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Do not use client.defineJob or any deprecated v2 patterns (e.g., eventTrigger) when defining tasks

Applied to files:

  • docs/tasks/overview.mdx
🧬 Code graph analysis (2)
packages/trigger-sdk/src/v3/hooks.ts (2)
packages/core/src/v3/lifecycle-hooks-api.ts (2)
  • AnyOnStartAttemptHookFunction (38-38)
  • lifecycleHooks (5-5)
packages/core/src/v3/lifecycleHooks/types.ts (1)
  • AnyOnStartAttemptHookFunction (47-47)
packages/core/src/v3/types/tasks.ts (3)
packages/trigger-sdk/src/v3/shared.ts (1)
  • Context (122-122)
packages/core/src/v3/lifecycleHooks/types.ts (2)
  • OnStartHookFunction (30-32)
  • OnStartAttemptHookFunction (43-45)
packages/core/src/v3/workers/taskExecutor.ts (11)
  • payload (364-416)
  • payload (418-454)
  • payload (682-782)
  • payload (784-849)
  • payload (851-916)
  • payload (918-928)
  • payload (930-994)
  • payload (996-1058)
  • payload (1060-1068)
  • payload (1070-1140)
  • payload (1352-1417)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: Analyze (javascript-typescript)

Comment on lines +118 to +124
export type StartAttemptFnParams = Prettify<{
ctx: Context;
init?: InitOutput;
/** Abort signal that is aborted when a task run exceeds it's maxDuration or if the task run is cancelled. Can be used to automatically cancel downstream requests */
signal: AbortSignal;
}>;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Remove init from StartAttempt params (not passed at runtime).

#callOnStartAttemptFunctions() never supplies init, so exposing it here is misleading and can cause incorrect usage.

Apply:

-export type StartAttemptFnParams = Prettify<{
-  ctx: Context;
-  init?: InitOutput;
-  /** Abort signal that is aborted when a task run exceeds it's maxDuration or if the task run is cancelled. Can be used to automatically cancel downstream requests */
-  signal: AbortSignal;
-}>;
+export type StartAttemptFnParams = Prettify<{
+  ctx: Context;
+  /** Abort signal that is aborted when a task run exceeds it's maxDuration or if the task run is cancelled. Can be used to automatically cancel downstream requests */
+  signal: AbortSignal;
+}>;

Run to confirm no code depends on init in StartAttempt:


🏁 Script executed:

#!/bin/bash
rg -nP 'StartAttemptFnParams|onStartAttempt\(' -C3

Length of output: 3813


Remove init from StartAttemptFnParams (not passed at runtime).

onStartAttempt hooks are invoked without init; the exported type is misleading and should be removed.

Apply:

-export type StartAttemptFnParams = Prettify<{
-  ctx: Context;
-  init?: InitOutput;
-  /** Abort signal that is aborted when a task run exceeds it's maxDuration or if the task run is cancelled. Can be used to automatically cancel downstream requests */
-  signal: AbortSignal;
-}>;
+export type StartAttemptFnParams = Prettify<{
+  ctx: Context;
+  /** Abort signal that is aborted when a task run exceeds it's maxDuration or if the task run is cancelled. Can be used to automatically cancel downstream requests */
+  signal: AbortSignal;
+}>;

Files to update: packages/core/src/v3/types/tasks.ts (around lines ~118–124). Also update any SDK hook typings that re-export/reference this type (e.g., packages/trigger-sdk/src/v3/hooks.ts).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type StartAttemptFnParams = Prettify<{
ctx: Context;
init?: InitOutput;
/** Abort signal that is aborted when a task run exceeds it's maxDuration or if the task run is cancelled. Can be used to automatically cancel downstream requests */
signal: AbortSignal;
}>;
export type StartAttemptFnParams = Prettify<{
ctx: Context;
/** Abort signal that is aborted when a task run exceeds it's maxDuration or if the task run is cancelled. Can be used to automatically cancel downstream requests */
signal: AbortSignal;
}>;
🤖 Prompt for AI Agents
In packages/core/src/v3/types/tasks.ts around lines 118–124, the exported
StartAttemptFnParams type incorrectly includes an optional init property which
is not provided at runtime for onStartAttempt hooks; remove the init property
from that type definition and update any downstream typings that re-export or
reference this type (for example packages/trigger-sdk/src/v3/hooks.ts) to use
the updated StartAttemptFnParams signature without init so the hook type
accurately reflects runtime parameters.

@ericallam ericallam merged commit a94a11f into main Nov 13, 2025
32 checks passed
@ericallam ericallam deleted the ea-branch-88 branch November 13, 2025 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants